package com.winchain.chainbill.bill.biz.repurchase.service.impl;

import com.shell.bee.base.exception.UnCheckMsgException;
import com.shell.bee.base.service.BaseService;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.persistence.transaction.Transaction;
import com.shell.bee.persistence.transaction.TransactionUtil;
import com.shell.framework.utils.SysDateUtil;
import com.winchain.chainbill.ChainBillUtil;
import com.winchain.chainbill.bill.base.po.CbDct;
import com.winchain.chainbill.bill.base.po.CbOpt;
import com.winchain.chainbill.bill.base.po.CbRec;
import com.winchain.chainbill.bill.base.po.CbRpur;
import com.winchain.chainbill.bill.base.service.CbDctService;
import com.winchain.chainbill.bill.base.service.CbRecService;
import com.winchain.chainbill.bill.biz.Bill;
import com.winchain.chainbill.bill.biz.BillEvent;
import com.winchain.chainbill.bill.biz.repurchase.rx.BillRpurDebitSubscriber;
import com.winchain.chainbill.bill.biz.repurchase.rx.BillRpurFileUploadSubscriber;
import com.winchain.chainbill.bill.biz.repurchase.rx.BillRpurSubscriber;
import com.winchain.chainbill.bill.biz.repurchase.rx.BillRpurSuccessMsgSubscriber;
import com.winchain.chainbill.bill.biz.repurchase.service.BillRpurPmtService;
import com.winchain.chainbill.bill.biz.repurchase.service.BillRpurService;
import com.winchain.chainbill.bill.biz.send.rx.BillMoveSubscriber;
import com.winchain.chainbill.bill.biz.send.rx.BillOptSubscriber;
import com.winchain.chainbill.bill.biz.send.service.BillCheckService;
import com.winchain.chainbill.bill.biz.send.service.BillService;
import com.winchain.chainbill.bill.biz.send.vo.BatchBillStats;
import org.apache.commons.logging.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import rx.Observable;

@Service("billRpurService")
public class BillRpurServiceImpl extends BaseService implements BillRpurService {
	@Autowired
	private CbRecService cbRecService;
	@Autowired
	private CbDctService cbDctService;
	@Autowired
	private BillService billService;
	@Autowired
	private BillCheckService billCheckService;
	@Autowired
	private BillOptSubscriber billOptSubscriber;
	@Autowired
	private BillMoveSubscriber billMoveSubscriber;
	@Autowired
	private BillRpurSubscriber billRpurSubscriber;
	@Autowired
	private BillRpurFileUploadSubscriber billRpurFileUploadSubscriber;
	@Autowired
	private BillRpurSuccessMsgSubscriber billRpurSuccessMsgSubscriber;
	@Autowired
	private BillRpurDebitSubscriber billRpurDebitSubscriber;
	@Autowired
	private BillRpurPmtService billRpurPmtService;

	public BatchBillStats<CbRpur> rpur(CbRpur rpur, String fileIds) {
		CbRec record = (CbRec) this.cbRecService.selectByKey(rpur.getBillId());
		CbDct cbDct = (CbDct) this.cbDctService.selectByKey(rpur.getDctId());

		rpur.setBuyerId(cbDct.getSellerId());
		rpur.setBuyerNm(cbDct.getSellerNm());

		rpur.setRpurDate(SysDateUtil.getSystemDate());
		rpur.setRpurAmt(cbDct.getDctAmt());
		String msg = this.billCheckService.checkBillRpur(record, rpur, cbDct);
		if (StringUtil.notEmpty(msg)) {
			throw new UnCheckMsgException(msg);
		}
		Bill<CbRpur> bill = this.billService.init(record, cbDct, rpur);

		return rpur(bill, fileIds);
	}

	private BatchBillStats<CbRpur> rpur(final Bill<CbRpur> bill, final String fileIds) {
		final BatchBillStats<CbRpur> stats = new BatchBillStats();
		final String[] pmtResult = new String[1];
		TransactionUtil.execute(new Transaction() {
			public void doInTransaction() {
				BillEvent<CbRpur> event = new BillEvent(bill);
				CbOpt opt = new CbOpt();
				opt.setCurState("S012");
				opt.setOptCode("E701");
				opt.setRemark("��������");

				event.setOperation(opt);
				event.setValue("fileIds", fileIds);

				Observable<BillEvent<CbRpur>> observers = Observable.just(event);
				observers.subscribe(BillRpurServiceImpl.this.billOptSubscriber);
				observers.subscribe(BillRpurServiceImpl.this.billRpurSubscriber);
				observers.subscribe(BillRpurServiceImpl.this.billMoveSubscriber);
				observers.subscribe(BillRpurServiceImpl.this.billRpurDebitSubscriber);
				observers.subscribe(BillRpurServiceImpl.this.billRpurFileUploadSubscriber);
				if (!ChainBillUtil.onlinePay()) {
					observers.subscribe(BillRpurServiceImpl.this.billRpurSuccessMsgSubscriber);
				}
				pmtResult[0] = ((String) event.getValue("pmtResult"));
				stats.addPassedRecord(event.getBill());
			}
		}, new int[0]);
		if ((ChainBillUtil.onlinePay()) && ("S".equals(pmtResult[0]))) {
			try {
				TransactionUtil.execute(new Transaction() {
					public void doInTransaction() {
						BatchBillStats<CbRpur> ret = BillRpurServiceImpl.this.billRpurPmtService
								.pmt(new String[] { bill.getRec().getBillId() });
						stats.setTxSnHost(ret.getTxSnHost());
					}
				}, new int[0]);
			} catch (Exception e) {
				this.logger.error("��������������������", e);
			}
		}
		return stats;
	}
}
